/*
 * =====================================================================================
 *
 *       Filename:  main.cpp
 *
 *    Description:
 *
 *        Version:  1.0
 *        Created:  2017年08月10日 09时47分00秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Crane (), wanghe@galaxyeye-tech.com
 *   Organization:  Galaxy-eye
 *
 * =====================================================================================
 */

#include <iostream>
#include <vector>
#include <assert.h>

class Record
{
    enum  Type {singleMid, doubleMid};

    // [midPos, toPos]
    Type midType;       //  aba singleMid,  abba -- doubleMid
    int  midPos;        //  singleMid or leftMid(doubleMid)
    int  toPos;

public:
    Record(int m = 0) {
        SetSingle();
        midPos = toPos = m;
    }

    int GetTo() const   { return toPos;        }
    void SetTo(int t)   { toPos = t;           }

    int GetType() const { return midType;      }
    void SetSingle()    { midType = singleMid; }
    void SetDouble()    { midType = doubleMid; }

    size_t GetLen() const {

        int rightLen = toPos - midPos + 1;      // [midPos, toPos]

        if (midType == singleMid)
            return  rightLen * 2 - 1;

        if (midType == doubleMid)
            return  rightLen * 2;

        assert(false || "can't reach here in GetLen()");
    }

    template<class Contain >
    bool isPair(int p1, int p2, const Contain &nums) {
        if (p1 < 0)
            return false;
        return  nums[p1] == nums[p2];
    }

    template<class Contain >
    bool NextPair(const Contain & nums) {
        int nextTo   = toPos + 1;
        int nextFrom = GetFrom() - 1;
        if ( isPair(nextTo, nextFrom, nums) )
        {
            toPos++;
            return true;
        }
        else
            return false;
    }

    size_t  GetFrom() const {
        int len = GetLen();
        assert( toPos + 1 >= len );     // 考虑到 nums[0]的情况， 所以 +1

        int from =  toPos + 1 - len;
        assert( from >= 0 );

        return from;
    }

    void showType() const {
        if (midType == singleMid)
            std::cout << "single mid:" << std::endl;
        else
        if ( midType == doubleMid )
            std::cout << "double mid:" << std::endl;
        else
            assert(false || "can't reach here");
    }

    void show() const {
        showType();
        std::cout << "midPos: " << midPos << std::endl;
        std::cout << "toPos: "  << toPos  << std::endl;
    }

    template<class Contain>
    void show(const Contain &nums) const {

        show();

        for (int i = GetFrom(); i <= toPos; i++)
        {
            std::cout << nums[i] << ", ";
        }
        std::cout << std::endl;
    }
};

// [first, last)
template<class Iterator>
int Max_Palindrome(Iterator first, Iterator last)
{
    std::vector<int>  nums;
    nums.reserve(15);
    std::copy(first, last, std::back_inserter(nums));

    Record  maxRecord;
    Record  curRecord;

    // 只遍历一次
    // 复杂度O(n)
    for (size_t i = 1; i < nums.size(); i++)
    {


        if (add > nums[i]) {
            curRecord.SetAll( curRecord.GetFrom(), i, add);
        } else {
            curRecord.SetAll(i, i, nums[i]);
        }

        if ( curRecord.GetMax() > maxRecord.GetMax())
            maxRecord = curRecord;
    }

    maxRecord.show(nums);

    return 0;
}

#define  ArraySize(array)       ( sizeof(array) / sizeof( array[0] ) )

int main(int argc, char **argv)
{
    {
        int nums[] = {-2, 5, 3, -6, 4, -8, 6};
        Record r;
        r.show(nums);
    }
    {
        int nums[] = {1, -2, 3, 10, -4, 7, 2, -5};
    }
}
